{
 "cells": [
  {
   "cell_type": "markdown",
   "source": [
    "# 数据重构\n",
    "### 关心索引怎么变，索引变对了数据就不会放错\n",
    "### 裂变stack：指定某层数的columns变为最内层的index，默认最内层\n",
    "### unstack：指定某层数的index变为最内层的columns，默认最内层"
   ],
   "metadata": {
    "collapsed": false
   }
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "   data1  data2\n",
      "0      2      2\n",
      "1      6      1\n",
      "2      3      9\n",
      "3      6      1\n",
      "4      0      1\n"
     ]
    }
   ],
   "source": [
    "import pandas as pd\n",
    "import numpy as np\n",
    "\n",
    "np.random.seed(123)\n",
    "df_obj = pd.DataFrame(np.random.randint(0,10, (5,2)), columns=['data1', 'data2'])\n",
    "print(df_obj)"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    },
    "ExecuteTime": {
     "end_time": "2024-05-03T05:35:50.229149900Z",
     "start_time": "2024-05-03T05:35:49.735470900Z"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0  data1    2\n",
      "   data2    2\n",
      "1  data1    6\n",
      "   data2    1\n",
      "2  data1    3\n",
      "   data2    9\n",
      "3  data1    6\n",
      "   data2    1\n",
      "4  data1    0\n",
      "   data2    1\n",
      "dtype: int32\n"
     ]
    }
   ],
   "source": [
    "# 对df进行stack，就会变成mutiindex的series\n",
    "\n",
    "stacked = df_obj.stack(level=0)  #stack内部带的参数level，选择哪一层column变为最内层index，这里只有一层\n",
    "#stacked = df_obj.stack()\n",
    "print(stacked)"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    },
    "ExecuteTime": {
     "end_time": "2024-05-03T05:42:44.281281300Z",
     "start_time": "2024-05-03T05:42:44.265734900Z"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "   data1  data2\n",
      "0      2      2\n",
      "1      6      1\n",
      "2      3      9\n",
      "3      6      1\n",
      "4      0      1\n",
      "--------------------------------------------------\n",
      "       0  1  2  3  4\n",
      "data1  2  6  3  6  0\n",
      "data2  2  1  9  1  1\n"
     ]
    }
   ],
   "source": [
    "# 对series进行unstack，默认操作内层索引\n",
    "print(stacked.unstack())\n",
    "print(\"-\"*50)\n",
    "\n",
    "# 通过level指定操作索引的级别\n",
    "print(stacked.unstack(level=0))"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    },
    "ExecuteTime": {
     "end_time": "2024-05-03T05:43:43.842169900Z",
     "start_time": "2024-05-03T05:43:43.797290500Z"
    }
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "### 多层索引df的stack和unstack"
   ],
   "metadata": {
    "collapsed": false
   }
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "            data1  data2\n",
      "cloth size              \n",
      "a     0         0      1\n",
      "      1         2      3\n",
      "      2         4      5\n",
      "b     0         6      7\n",
      "      1         8      9\n",
      "      2        10     11\n",
      "c     0        12     13\n",
      "      1        14     15\n",
      "      2        16     17\n",
      "d     0        18     19\n",
      "      1        20     21\n",
      "      2        22     23\n"
     ]
    }
   ],
   "source": [
    "import pandas as pd\n",
    "import numpy as np\n",
    "\n",
    "index1 = pd.MultiIndex.from_arrays([['a', 'a', 'a', 'b', 'b', 'b', 'c', 'c', 'c', 'd', 'd', 'd'],\n",
    "                [0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2]], names=['cloth', 'size'])\n",
    "\n",
    "df= pd.DataFrame(np.arange(24).reshape(12,2),index=index1,columns=['data1','data2'])\n",
    "print(df)"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    },
    "ExecuteTime": {
     "end_time": "2024-05-03T05:46:18.851140700Z",
     "start_time": "2024-05-03T05:46:18.822843600Z"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "      data1             data2            \n",
      "cloth     a   b   c   d     a   b   c   d\n",
      "size                                     \n",
      "0         0   6  12  18     1   7  13  19\n",
      "1         2   8  14  20     3   9  15  21\n",
      "2         4  10  16  22     5  11  17  23\n",
      "--------------------------------------------------\n",
      "MultiIndex([('data1', 'a'),\n",
      "            ('data1', 'b'),\n",
      "            ('data1', 'c'),\n",
      "            ('data1', 'd'),\n",
      "            ('data2', 'a'),\n",
      "            ('data2', 'b'),\n",
      "            ('data2', 'c'),\n",
      "            ('data2', 'd')],\n",
      "           names=[None, 'cloth'])\n"
     ]
    }
   ],
   "source": [
    "df_s=df.unstack(level=0)  #把行索引中的一个级别拿到列索引\n",
    "print(df_s)\n",
    "print(\"-\"*50)\n",
    "\n",
    "print(df_s.columns) #看到columns索引变为层级索引\n"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    },
    "ExecuteTime": {
     "end_time": "2024-05-03T05:48:54.245580400Z",
     "start_time": "2024-05-03T05:48:54.206540700Z"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "cloth       a   b   c   d\n",
      "size                     \n",
      "0    data1  0   6  12  18\n",
      "     data2  1   7  13  19\n",
      "1    data1  2   8  14  20\n",
      "     data2  3   9  15  21\n",
      "2    data1  4  10  16  22\n",
      "     data2  5  11  17  23\n"
     ]
    }
   ],
   "source": [
    "print(df_s.stack(0))  #把columns上的0层索引放到index的内层索引"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-05-03T06:14:44.265793900Z",
     "start_time": "2024-05-03T06:14:44.226936800Z"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "            data1  data2\n",
      "size cloth              \n",
      "0    a          0      1\n",
      "     b          6      7\n",
      "     c         12     13\n",
      "     d         18     19\n",
      "1    a          2      3\n",
      "     b          8      9\n",
      "     c         14     15\n",
      "     d         20     21\n",
      "2    a          4      5\n",
      "     b         10     11\n",
      "     c         16     17\n",
      "     d         22     23\n"
     ]
    }
   ],
   "source": [
    "print(df_s.stack(1))  # 把第一层的列索引放到行索引的内层索引"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-05-03T06:16:03.370756100Z",
     "start_time": "2024-05-03T06:16:03.338760500Z"
    }
   }
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.6"
  },
  "pycharm": {
   "stem_cell": {
    "cell_type": "raw",
    "source": [
     "# 11 数据合并(pd.concat)\n"
    ],
    "metadata": {
     "collapsed": false
    }
   }
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}
